home *** CD-ROM | disk | FTP | other *** search
- #define LIBQDISPLAY_CORE
- #include "../include/libqdisplay.h"
-
- struct texture **cachedFaces;
-
- void InitFaceCache(__memBase)
- {
- if (!(cachedFaces = (struct texture **)kmalloc(bspMem->shared.quake1.numfaces * sizeof(struct texture *))))
- Error(failed_memory, bspMem->shared.quake1.numfaces * sizeof(struct texture *), "face-cache");
- }
-
- static void GetMipMaps(__memBase, struct texture *Text, int TMipMap)
- {
- struct dmiptexlump_t *mtl = (struct dmiptexlump_t *)bspMem->shared.quake1.dtexdata;
- struct mipmap *mip = (struct mipmap *)(bspMem->shared.quake1.dtexdata + mtl->dataofs[TMipMap]);
- short int i;
-
- if (mip->name[0] == WARP_MIPMAP) {
- switch (mip->name[1]) {
- case 'w': Text->textureType = WATER_TYPE; break; /* *w(ater)... */
- case 's': Text->textureType = SLIME_TYPE; break; /* *s(lime)... */
- case 'l': Text->textureType = LAVA_TYPE; break; /* *l(ava)... */
- case 't': Text->textureType = TELEPORT_TYPE; break; /* *t(eleport)... */
- default: Text->textureType = OTHER_TYPE; break; /* *... */
- }
- Text->mipMaps[MIPMAP_0].rawBody.width = WARP_X;
- Text->mipMaps[MIPMAP_0].rawBody.height = WARP_Y;
- Text->mipMaps[MIPMAP_0].rawBody.size = WARP_X * WARP_Y;
- Text->mipMaps[MIPMAP_0].newBody.width = WARP_X;
- Text->mipMaps[MIPMAP_0].newBody.height = WARP_Y;
- Text->mipMaps[MIPMAP_0].newBody.size = WARP_X * WARP_Y;
- Text->textGradient.u = 0;
- Text->textGradient.v = 0;
- }
- else if (!__strncmp(mip->name, SKY_MIPMAP, 3)) {
- Text->textureType = SKY_TYPE;
- Text->mipMaps[MIPMAP_0].rawBody.width = SKY_X;
- Text->mipMaps[MIPMAP_0].rawBody.height = SKY_Y;
- Text->mipMaps[MIPMAP_0].rawBody.size = SKY_X * SKY_Y;
- Text->mipMaps[MIPMAP_0].newBody.width = SKY_X;
- Text->mipMaps[MIPMAP_0].newBody.height = SKY_Y;
- Text->mipMaps[MIPMAP_0].newBody.size = SKY_X * SKY_Y;
- Text->textGradient.u = 0;
- Text->textGradient.v = 0;
- }
- else {
- if (mip->name[0] == ANIM_MIPMAP)
- Text->textureType = ANIM_TYPE;
- else
- Text->textureType = WALL_TYPE;
-
- Text->mipMaps[MIPMAP_0].rawBody.width = LittleLong(mip->width);
- Text->mipMaps[MIPMAP_0].rawBody.height = LittleLong(mip->height);
- Text->mipMaps[MIPMAP_0].rawBody.size = Text->mipMaps[MIPMAP_0].rawBody.width * Text->mipMaps[MIPMAP_0].rawBody.height;
- Text->mipMaps[MIPMAP_0].newBody.width = Text->faceExtent.u10;
- Text->mipMaps[MIPMAP_0].newBody.height = Text->faceExtent.v10;
- Text->mipMaps[MIPMAP_0].newBody.size = Text->mipMaps[MIPMAP_0].newBody.width * Text->mipMaps[MIPMAP_0].newBody.height;
- Text->textGradient.u = Text->faceExtent.u0;
- Text->textGradient.v = Text->faceExtent.v0;
- }
- Text->mipMaps[MIPMAP_0].rawBody.data = (unsigned char *)mip + LittleLong(mip->offsets[MIPMAP_0]);
- Text->mipMaps[MIPMAP_0].step = 16;
- Text->mipMaps[MIPMAP_0].shift = 4;
- Text->mipMaps[MIPMAP_0].row = Text->mipMaps[MIPMAP_0].newBody.width - Text->mipMaps[MIPMAP_0].step;
- if ((Text->mipMaps[MIPMAP_0].y = Text->faceExtent.v0 % Text->mipMaps[MIPMAP_0].rawBody.height) < 0)
- Text->mipMaps[MIPMAP_0].y += Text->mipMaps[MIPMAP_0].rawBody.height;
- if ((Text->mipMaps[MIPMAP_0].x0 = Text->faceExtent.u0 % Text->mipMaps[MIPMAP_0].rawBody.width) < 0)
- Text->mipMaps[MIPMAP_0].x0 += Text->mipMaps[MIPMAP_0].rawBody.width;
- Text->mipMaps[MIPMAP_0].rescale = scalw((double)(8), -3); /* / 8.0; */
-
- for (i = MIPMAP_1; i < MIPMAP_MAX; i++) { /* an enum cycles, produces no overflow */
- Text->mipMaps[i].rawBody.data = (unsigned char *)mip + LittleLong(mip->offsets[i]);
- Text->mipMaps[i].rawBody.width = Text->mipMaps[MIPMAP_0].rawBody.width >> i;
- Text->mipMaps[i].rawBody.height = Text->mipMaps[MIPMAP_0].rawBody.height >> i;
- Text->mipMaps[i].rawBody.size = Text->mipMaps[MIPMAP_0].rawBody.size >> i >> i;
- Text->mipMaps[i].newBody.width = Text->mipMaps[MIPMAP_0].newBody.width >> i;
- Text->mipMaps[i].newBody.height = Text->mipMaps[MIPMAP_0].newBody.height >> i;
- Text->mipMaps[i].newBody.size = Text->mipMaps[MIPMAP_0].newBody.size >> i >> i;
- Text->mipMaps[i].step = 16 >> i;
- Text->mipMaps[i].shift = 4 - i;
- Text->mipMaps[i].row = Text->mipMaps[i].newBody.width - Text->mipMaps[i].step;
- Text->mipMaps[i].rescale = scalw(Text->mipMaps[MIPMAP_0].rescale, -i);
- Text->mipMaps[i].y = Text->mipMaps[MIPMAP_0].y >> i;
- Text->mipMaps[i].x0 = Text->mipMaps[MIPMAP_0].x0 >> i;
- }
-
- {
- int j;
- int r = 0, g = 0, b = 0;
- struct rgb rgb;
- unsigned char *textFlow = Text->mipMaps[MIPMAP_0].rawBody.data;
-
- for (j = Text->mipMaps[MIPMAP_0].rawBody.size; j > 0; j--) {
- int k = (int)*textFlow++;
-
- r += cachedPalette[k].r;
- g += cachedPalette[k].g;
- b += cachedPalette[k].b;
- }
- rgb.r = r / Text->mipMaps[MIPMAP_0].rawBody.size;
- rgb.g = g / Text->mipMaps[MIPMAP_0].rawBody.size;
- rgb.b = b / Text->mipMaps[MIPMAP_0].rawBody.size;
- Text->textureColor = (unsigned char)Match(&rgb, cachedPalette);
- }
-
- if (!(Text->tiled = (void *)kmalloc((Text->mipMaps[MIPMAP_0].newBody.size + 1) * localDim.frameBPP)))
- Error(failed_memory, (Text->mipMaps[MIPMAP_0].newBody.size + 1) * localDim.frameBPP, mip->name);
-
- Text->texChanged = TRUE; /* be very safe */
- }
-
- static void GetExtents(__memBase, int face, struct texture *Text, int TInfo)
- {
- float uv[32][2], *u, *v, umin, umax, vmin, vmax;
- short int i, n = bspMem->shared.quake1.dfaces[face].numedges;
- int *se = &bspMem->shared.quake1.dsurfedges[bspMem->shared.quake1.dfaces[face].firstedge + n];
-
- u = bspMem->shared.quake1.texinfo[TInfo].vecs[0];
- v = bspMem->shared.quake1.texinfo[TInfo].vecs[1];
-
- for (i = n - 1; i >= 0; --i) {
- int j = *--se;
- float *loc;
-
- if (j < 0)
- loc = bspMem->shared.quake1.dvertexes[bspMem->shared.quake1.dedges[-j].v[1]].point;
- else
- loc = bspMem->shared.quake1.dvertexes[bspMem->shared.quake1.dedges[ j].v[0]].point;
-
- uv[i][0] = DotProduct(loc, u) + u[3];
- uv[i][1] = DotProduct(loc, v) + v[3];
- }
- umin = umax = uv[0][0];
- vmin = vmax = uv[0][1];
- for (i = n - 1; i >= 0; --i) {
- if (uv[i][0] < umin)
- umin = uv[i][0];
- else if (uv[i][0] > umax)
- umax = uv[i][0];
- if (uv[i][1] < vmin)
- vmin = uv[i][1];
- else if (uv[i][1] > vmax)
- vmax = uv[i][1];
- }
-
- Text->faceExtent.u0 = (int)(umin) & ~15;
- Text->faceExtent.v0 = (int)(vmin) & ~15;
- Text->faceExtent.u1 = (int)(ceil(scalw(umax, -4))) << 4; /* / 16 */
- Text->faceExtent.v1 = (int)(ceil(scalw(vmax, -4))) << 4; /* / 16 */
- Text->faceExtent.u10 = Text->faceExtent.u1 - Text->faceExtent.u0;
- Text->faceExtent.v10 = Text->faceExtent.v1 - Text->faceExtent.v0;
-
- if ((bspMem->shared.quake1.dfaces[face].lightofs != -1) && (bspMem->shared.quake1.lightdatasize)) {
- Text->lightdata = &bspMem->shared.quake1.dlightdata[bspMem->shared.quake1.dfaces[face].lightofs];
-
- Text->lightmap.width = ((Text->faceExtent.u10) >> 4) + 1;
- Text->lightmap.height = ((Text->faceExtent.v10) >> 4) + 1;
- Text->lightmap.size = Text->lightmap.width * Text->lightmap.height;
- if (!(Text->lightmap.data = (unsigned char *)kmalloc((Text->lightmap.size + 1) * sizeof(int))))
- Error(failed_memory, (Text->lightmap.size + 1) * sizeof(int), "lightmap");
-
- for (i = 0; i < MAXLIGHTMAPS; i++) {
- short int lightStyle;
-
- lightStyle = (short int)bspMem->shared.quake1.dfaces[face].styles[i];
-
- if (lightStyle == 255)
- break;
- if (lightStyle > 11)
- lightStyle = 0;
-
- Text->lightSString[i] = &lightstyleStrings[lightStyle][0];
- Text->lightSLength[i] = lightstyleLengths[lightStyle];
- }
- }
- else
- Text->lightdata = 0;
-
- Text->texChanged = TRUE; /* be very safe */
- }
-
- static void GetGradients(__memBase, int face, struct texture *Text, int TInfo)
- {
- struct dplane_t *plane = Text->textGradient.plane = &bspMem->shared.quake1.dplanes[bspMem->shared.quake1.dfaces[face].planenum];
- float dot, dot0, dot1;
- vec3_t norm;
- float *vec0 = bspMem->shared.quake1.texinfo[TInfo].vecs[0];
- float *vec1 = bspMem->shared.quake1.texinfo[TInfo].vecs[1];
-
- CrossProduct(vec0, vec1, norm);
-
- dot = DotProduct(norm, plane->normal);
-
- if ((dot0 = -DotProduct(vec0, plane->normal) / dot)) /* for setup_uv_vector */
- VectorMA(vec0, dot0, norm, Text->textGradient.uv0);
- else
- VectorCopy(vec0, Text->textGradient.uv0);
-
- if ((dot1 = -DotProduct(vec1, plane->normal) / dot)) /* for setup_uv_vector */
- VectorMA(vec1, dot1, norm, Text->textGradient.uv1);
- else
- VectorCopy(vec1, Text->textGradient.uv1);
-
- VectorScale(norm, (plane->dist / dot), Text->textGradient.scaled); /* for setup_origin_vector; */
-
- Text->textGradient.u -= vec0[3];
- Text->textGradient.v -= vec1[3];
- Text->texChanged = TRUE; /* be very safe */
- }
-
- struct texture *CacheFace(__memBase, int face)
- {
- struct texture *Text;
- int TInfo = bspMem->shared.quake1.dfaces[face].texinfo;
- int TMipMap = bspMem->shared.quake1.texinfo[TInfo].miptex;
-
- if (!(Text = (struct texture *)kmalloc(sizeof(struct texture))))
- Error(failed_memory, sizeof(struct texture), "texture cache");
-
- GetExtents(bspMem, face, Text, TInfo);
- GetMipMaps(bspMem, Text, TMipMap);
- GetGradients(bspMem, face, Text, TInfo);
- Text->texChanged = TRUE; /* be very safe */
-
- return Text;
- }
-